package org.apache.cordova.plugin;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.apache.cordova.PluginResult.Status;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Environment;
import android.util.Log;

import com.mobileworld.MainActivity;


public class SysFuncPlugin extends CordovaPlugin{
	private static String TAG = "SysFuncPlugin";
	
    /**
     * {@inheritDoc}
     */
    @Override	
    public boolean execute(String action, JSONArray data,
    		final CallbackContext callbackContext) throws JSONException {
    	Log.d(TAG, "SysFuncPlugin in,action:" + action);
        if ("exitApp".equals(action)) {
        	System.exit(0); 
        }
		//关闭加载页
		if ("closeLoadingPage".equals(action)) {
			MainActivity activity = (MainActivity)this.cordova.getActivity();
			activity.handler.obtainMessage(activity.MSG_CLOSE_LOADPAGE).sendToTarget();
		}
		//展示加载进度
		if ("showProgress".equals(action)) {
			MainActivity activity = (MainActivity)this.cordova.getActivity();
			activity.handler.obtainMessage(activity.MSG_PROG_INSHOW,data).sendToTarget();
		}
        if ("envSetup".equals(action)) {
        	String setupData = data.getString(0);
        	this.envSetup(setupData); 
        	return true;
        }  
        //检查多媒体是否可用
        if ("mediaCheck".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
					AudioRecord recorder = new AudioRecord(
							MediaRecorder.AudioSource.MIC, 44100,
							AudioFormat.CHANNEL_IN_MONO,
							AudioFormat.ENCODING_PCM_16BIT, 8000);
					Log.d(TAG, "recorder.getState():" + recorder.getState());
					if (recorder.getState() == AudioRecord.STATE_UNINITIALIZED) {
						Log.w(TAG, "err in mediaCheck");
						JSONObject result = new JSONObject();
						callbackContext.error(result);
					}
					Log.e(TAG, "mediaCheck ok");
					PluginResult result = new PluginResult(Status.OK, "ok");
					result.setKeepCallback(true);
					callbackContext.sendPluginResult(result);                   
                }
            });
            return true;         	
        }         
        if ("clearSplash".equals(action)) {
        	this.clearSplash(); 
        	return true;
        }          
        if ("copyAssetsFile".equals(action)) {
        	String sourceFile = data.getString(0);
        	String destFile = data.getString(1);
        	String targetPath = this.copyAssetsFile(sourceFile,destFile); 
        	if(targetPath==null){
        		JSONObject result = new JSONObject();
        		result.put("reason", "copyAssetsFile error");
        		callbackContext.error(result);
        		return true;
        	}
            PluginResult result = new PluginResult(Status.OK, targetPath);
            result.setKeepCallback(true);
            callbackContext.sendPluginResult(result);  
            return true;
        }      
        if ("unzipFile".equals(action)) {
        	String path = data.getString(0);
        	String zipname = data.getString(1);
        	try{
        		this.extractFolder(path, zipname);
                PluginResult result = new PluginResult(Status.OK, "ok");
                result.setKeepCallback(true);
                callbackContext.sendPluginResult(result);  
                return true;
        	}catch(Exception e){
        		Log.e(TAG, "error when unzip",e);
        		JSONObject result = new JSONObject();
        		result.put("reason", e.getMessage());
        		callbackContext.error(result);
        	}       	
        }  
        if ("unzipFileExtra".equals(action)) {
        	String path = data.getString(0);
        	String zipname = data.getString(1);
        	String targetPath = data.getString(1);
        	try{
        		this.extractFolder(path, zipname);
                PluginResult result = new PluginResult(Status.OK, "ok");
                result.setKeepCallback(true);
                callbackContext.sendPluginResult(result);  
                return true;
        	}catch(Exception e){
        		Log.e(TAG, "error when unzip",e);
        		JSONObject result = new JSONObject();
        		result.put("reason", e.getMessage());
        		callbackContext.error(result);
        	}       	
        }         
        return false;
    }
    
    /*
     * 初始化环境变量
     */
    public void envSetup(String setupData) {
        try {
        	Log.d(TAG, "setupData in:" + setupData);
        	JSONObject jsonObj = new JSONObject(setupData);
			MainActivity activity = (MainActivity)this.cordova.getActivity();
        	activity.initEnvironment(1);
        } catch (JSONException e) {
        	Log.e(TAG, "err in envSetup",e);
        }     	   	
	}

    /*
     * 检查音频是否可用
     */
    public void mediaCheck() throws Exception{
        try {
        	new AudioRecord(MediaRecorder.AudioSource.MIC, 44100,
        			AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 8000);
        } catch (Exception e) {
        	Log.e(TAG, "err in mediaCheck",e);
        	throw e;
        }     	   	
	}
    
    /*
     * 拷贝assets目录下的文件
     */
    public String copyAssetsFile(String sourceFile,String destFile) {
        try {
        	InputStream in = this.cordova.getActivity().getAssets().open(sourceFile);
        	File dest = new File(Environment.getExternalStorageDirectory(),destFile);
        	OutputStream out = new FileOutputStream(dest);
        	byte[] buf = new byte[1024];
        	int len;
        	while ((len = in.read(buf)) > 0) {
        		out.write(buf, 0, len);
        	} 
        	in.close();
        	out.close();
        	return dest.getAbsolutePath();
        } catch (IOException e) {
        	Log.e(TAG, "err in copyAssetsFile",e);
        }     	 
        return null;
	}
 
    /*
     * 解压缩zip文件
     */
	public void extractFolder(String path,String zipFile) throws ZipException, IOException{
		  this.extractFolderExtra(path, zipFile, path);
		}
    /*
     * 解压缩zip文件
     */
	public void extractFolderExtra(String path,String zipFile,String targetPath) throws ZipException, IOException{
		   // System.out.println(zipFile);
		    int BUFFER = 2048;	    
		    File file = new File(Environment.getExternalStorageDirectory(),path + "/" + zipFile);
		    ZipFile zip = new ZipFile(file);
		    String newPath = targetPath;

		    new File(Environment.getExternalStorageDirectory(),newPath).mkdir();
		    Enumeration zipFileEntries = zip.entries();

		    // Process each entry
		    while (zipFileEntries.hasMoreElements())
		    {
		        // grab a zip file entry
		        ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
		        String currentEntry = entry.getName();
		        File destFile = new File(Environment.getExternalStorageDirectory(),newPath+ "/" + currentEntry);
		        //destFile = new File(newPath, destFile.getName());
		        File destinationParent = destFile.getParentFile();

		        // create the parent directory structure if needed
		        destinationParent.mkdirs();

		        if (!entry.isDirectory())
		        {
		            BufferedInputStream is = new BufferedInputStream(zip
		            .getInputStream(entry));
		            int currentByte;
		            // establish buffer for writing file
		            byte data[] = new byte[BUFFER];

		            // write the current file to disk
		            FileOutputStream fos = new FileOutputStream(destFile);
		            BufferedOutputStream dest = new BufferedOutputStream(fos,
		            BUFFER);

		            // read and write until last byte is encountered
		            while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
		                dest.write(data, 0, currentByte);
		            }
		            dest.flush();
		            dest.close();
		            is.close();
		        }
		    }
		}
	
    /*
     * 清除启动画面背景
     */
    public void clearSplash() {
		MainActivity activity = (MainActivity)this.cordova.getActivity();
    	Log.d(TAG, "call clear splash");
    }
}
